home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-06-24 | 17.2 KB | 635 lines | [TEXT/MPS ] |
- // UDrawShapes.cp
- // Copyright © 1994-95 by Apple Computer, Inc. All rights reserved.
-
- #ifndef __USHAPEVIEW__
- #include "UShapeView.h"
- #endif
-
- // MacApp
-
- #ifndef __UCLIPBOARDMGR__
- #include <UClipboardMgr.h>
- #endif
-
- #ifndef __UMEMORY__
- #include <UMemory.h>
- #endif
-
- #ifndef __UMENUMGR__
- #include <UMenuMgr.h>
- #endif
-
- #ifndef __UPRINTING__
- #include <UPrinting.h>
- #endif
-
- #ifndef __UMACAPPUTILITIES__
- #include <UMacAppUtilities.h>
- #endif
-
- // Toolbox
-
- #ifndef __PICKER__
- #include <Picker.h>
- #endif
-
- #ifndef __TOOLUTILS__
- #include <ToolUtils.h>
- #endif
-
- // DrawShapes
-
- #ifndef __SHAPECOMMANDS__
- #include "ShapeCommands.h"
- #endif
-
- #ifndef __TOOLSMENU__
- #include "ToolsMenu.h"
- #endif
-
- #ifndef __UDRAWSHAPES__
- #include "UDrawShapes.h"
- #endif
-
- #ifndef __UPICTSHAPE__
- #include "UPictShape.h"
- #endif
-
- #ifndef __USHAPES__
- #include "UShapes.h"
- #endif
-
- #ifndef __USHAPESDOCUMENT__
- #include "UShapesDocument.h"
- #endif
-
- #ifndef __UTEXTSHAPE__
- #include "UTextShape.h"
- #endif
-
- //----------------------------------------------------------------------------------------
- // Resources
-
- #define kPickerPrompt 256
-
- // Menus
- const short mColor = 7; // the Color menu resource id
-
- //--------------------------------------------------------------------------------------------------
- // Data types used for storing shapes in the Desk Scrap
-
- struct ShapeClipRecord {
- short theNumberOfShapes;
- CRect theBoundingBox;
- ShapeData theShapes[1536];
- };
-
- typedef ShapeClipRecord* PShapesOnClipboard;
- typedef PShapesOnClipboard* ShapesOnClipboard;
-
- //========================================================================================
- // CLASS TShapeView
- //========================================================================================
- #undef Inherited
- #define Inherited TView
-
- #pragma segment AInit
- MA_DEFINE_CLASS_M1(TShapeView, Inherited);
-
- //----------------------------------------------------------------------------------------
- // TShapeView Constructor
- //----------------------------------------------------------------------------------------
- #pragma segment AOpen
-
- TShapeView::TShapeView()
- {
- fDragging = false;
- fShapeDocument = NULL;
- fClickPt = gZeroPt;
- }
-
- //----------------------------------------------------------------------------------------
- // TShapeView::IShapeView:
- //----------------------------------------------------------------------------------------
- #pragma segment AOpen
-
- void TShapeView::IShapeView(TShapeDocument* itsDocument, Boolean forClipboard)
- {
- VPoint itsLocation;
- VPoint itsSize;
- SizeDeterminer sd;
-
- SetVPt(itsSize, kMaxCoord, kMaxCoord);
- if (forClipboard)
- sd = sizeVariable;
- else
- sd = sizeFillPages;
- this->IView(itsDocument, NULL, gZeroVPt, itsSize, sd, sd);
-
- fShapeDocument = itsDocument;
-
- if (!forClipboard)
- {
- TStdPrintHandler* printHandler = new TStdPrintHandler;
- printHandler->IStdPrintHandler(itsDocument, this, !kSquareDots, kFixedSize, kFixedSize);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // TShapeView::DoPostCreate:
- //----------------------------------------------------------------------------------------
- #pragma segment AOpen
-
- void TShapeView::DoPostCreate(TDocument* itsDocument) // Override
- {
- Inherited::DoPostCreate(itsDocument);
- fShapeDocument = (TShapeDocument*)itsDocument;
-
- this->AddAdorner(gSelectionAdorner, kDrawView, false);
- }
-
- //----------------------------------------------------------------------------------------
- // TShapeView::CalcMinFrame:
- //----------------------------------------------------------------------------------------
- #pragma segment AOpen
-
- void TShapeView::CalcMinFrame(VRect& minFrame) // Override
- {
- short numberOfShapes;
- CRect aRect;
- VPoint minSize;
-
- Inherited::CalcMinFrame(minFrame);
-
- fShapeDocument->SurveyShapes(false, numberOfShapes, aRect);
- minFrame.right = minFrame.left + Max(100, aRect.right);
- minFrame.bottom = minFrame.top + Max(100, aRect.bottom);
- }
-
- //----------------------------------------------------------------------------------------
- // TShapeView::ContainsClipType:
- //----------------------------------------------------------------------------------------
- #pragma segment ShapeRes
-
- Boolean TShapeView::ContainsClipType(ResType aType) // Override
- {
- return (aType == kShapeClipType);
- }
-
- //----------------------------------------------------------------------------------------
- // TShapeView::Deselect:
- //----------------------------------------------------------------------------------------
- #pragma segment ShapeRes
-
- void TShapeView::Deselect()
- {
- this->DoHighlightSelection(hlOn, hlOff);
-
- fShapeDocument->DeselectShapes();
- }
-
- //----------------------------------------------------------------------------------------
- // TShapeView::DoHighlightSelection:
- //----------------------------------------------------------------------------------------
- #pragma segment ShapeRes
-
- void TShapeView::DoHighlightSelection(HLState fromHL, HLState toHL) // Override
- {
- fShapeDocument->HiliteShapes(this, fromHL, toHL);
- }
-
- //----------------------------------------------------------------------------------------
- // TShapeView::DoMenuCommand:
- //----------------------------------------------------------------------------------------
- #pragma segment ASelCommand
-
- void TShapeView::DoMenuCommand(CommandNumber aCommandNumber) // Override
- {
- switch (aCommandNumber)
- {
- case cCut:
- case cCopy:
- {
- TShapeCutCopyCommand* shapeCutCopyCommand = new TShapeCutCopyCommand;
- shapeCutCopyCommand->IShapeCutCopyCommand(aCommandNumber, this);
- this->PostCommand(shapeCutCopyCommand);
- }
- break;
-
- case cPaste:
- {
- TShapePasteCommand* shapePasteCommand = new TShapePasteCommand;
- shapePasteCommand->IShapePasteCommand(this);
- this->PostCommand(shapePasteCommand);
- }
- break;
-
- case cClear:
- {
- TShapeClearCommand* shapeClearCommand = new TShapeClearCommand;
- shapeClearCommand->IShapeClearCommand(this);
- this->PostCommand(shapeClearCommand);
- }
- break;
-
- #if qDebug
- case cRecalcExtent:
- this->AdjustFrame();
- break;
- #endif
-
- case cSelectAll:
- if (this->Focus())
- this->SelectAllShapes();
- break;
-
- case cPickColor:
- this->PickColor();
- break;
-
- case cBetterFeedback:
- gBetterFeedback = !gBetterFeedback;
- break;
-
- default:
- if (!this->IsMenuColor(aCommandNumber))
- Inherited::DoMenuCommand(aCommandNumber);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // TShapeView::DoMouseCommand:
- //----------------------------------------------------------------------------------------
- #pragma segment ASelCommand
-
- void TShapeView::DoMouseCommand(VPoint& theMouse,
- TToolboxEvent* event,
- CPoint /*hysteresis*/) // Override
- {
- TToolsPalette* palette = GetToolsPalette();
- CPoint qdPt = ViewToQDPt(theMouse);
- fClickPt = qdPt;
- short currentTool = palette->GetCurrTool();
- if (currentTool > 0) // draw mode
- {
- FailSpaceIsLow(); // Make sure we aren't low on memory
- this->Deselect();
-
- // Clone appropriate shape
- TShape* shape = GetShapeInArray(currentTool);
- FailNonObject(shape);
-
- MAVolatileInit(TShape*, protoShape, (TShape*)shape->Clone());
- FailInfo fi;
-
- Try(fi)
- {
- // Make sure cloning the shape left us with enough memory to continue.
- FailSpaceIsLow();
-
- TShapeSketcher* shapeSketcher = new TShapeSketcher;
- shapeSketcher->IShapeSketcher(this, protoShape, theMouse, event->IsOptionKeyPressed());
- fi.Success();
- this->PostCommand(shapeSketcher);
- }
- else
- {
- FreeIfObject(protoShape);
- fi.ReSignal();
- }
- }
- else // select mode
- {
- TShape* shapeUnderMouse = fShapeDocument->ShapeUnderMouse(qdPt);
- if (shapeUnderMouse == NULL) // area select
- {
- if (!event->IsShiftKeyPressed())
- this->Deselect();
- TShapeSelector* shapeSelector = new TShapeSelector;
- shapeSelector->IShapeSelector(cMouseCommand, this, theMouse);
- this->PostCommand(shapeSelector);
- }
- else // shape select/move/...
- {
- if (!(shapeUnderMouse->IsSelected() || event->IsShiftKeyPressed()))
- this->Deselect();
-
- if (event->IsShiftKeyPressed())
- {
- shapeUnderMouse->SetSelected(!shapeUnderMouse->IsSelected());
- if (shapeUnderMouse->IsSelected())
- shapeUnderMouse->Highlight(hlOff, hlOn, this);
- else
- shapeUnderMouse->Highlight(hlOn, hlOff, this);
- }
- else if (!shapeUnderMouse->IsSelected())
- {
- shapeUnderMouse->SetSelected(true);
- this->DoHighlightSelection(hlOff, hlOn);
- }
-
- if (shapeUnderMouse->IsSelected())
- {
- TShapeDragger* shapeDragger = new TShapeDragger;
- shapeDragger->IShapeDragger(this, theMouse);
- this->PostCommand(shapeDragger);
- }
- }
- }
- }
-
- //----------------------------------------------------------------------------------------
- // TShapeView::DoSetupMenus
- //----------------------------------------------------------------------------------------
- #pragma segment ARes
-
- void TShapeView::DoSetupMenus() // Override
- {
- Inherited::DoSetupMenus();
-
- Boolean anySelection = false;
- Boolean anyShapes = false;
-
- // Find out if we are low on memory. If we are then we'll disable all
- // memory-intensive commands.
- Boolean haveMemory = !MemSpaceIsLow();
-
- // Check every virtual shape
- fShapeDocument->AnyShapesSelected(anySelection, anyShapes);
-
- // Enable the Patterns menu if there is a selection
- Enable(cPatterns, anySelection);
-
- if (anySelection && (qNeedsColorQD || gConfiguration.hasColorQD))
- {
- // Enable each of the Color menu items, if the Color menu is present
- MenuHandle aMenuHandle = GetMenuHandle(mColor);
- if (aMenuHandle)
- {
- short itemCount = CountMItems(aMenuHandle);
- for (short item = 1; item <= itemCount; item++)
- {
- // There can be more than 31 menu entries with scrolling menus,
- // but trying to enable an item with number > 31 is bad news.
- // If the menu itself is enabled (which it will be in MacApp
- // if any of the first 31 items is enabled), then the extras
- // will always be enabled.
- // Don't enable line separators
- CStr255 itemName;
- GetMenuItemText(aMenuHandle, item, itemName);
- if (item <= 31 && itemName != "-")
- EnableItem(aMenuHandle, item);
- }
- }
- }
-
- #if qDebug
- Enable(cRecalcExtent, true);
- #endif
- Enable(cCut, anySelection && haveMemory);
- Enable(cCopy, anySelection && haveMemory);
- if (haveMemory)
- {
- gClipboardMgr->CanPaste(kShapeClipType);
- gClipboardMgr->CanPaste('PICT');
- gClipboardMgr->CanPaste('TEXT');
- }
- Enable(cClear, anySelection);
-
- Enable(cSelectAll, anyShapes);
- EnableCheck(cBetterFeedback, true, gBetterFeedback);
- }
-
- //----------------------------------------------------------------------------------------
- // TShapeView::DoSetCursor
- //----------------------------------------------------------------------------------------
- #pragma segment ShapeRes
-
- void TShapeView::DoSetCursor(const VPoint& localPoint, RgnHandle cursorRegion) // Override
- {
- CPoint qdPoint = ViewToQDPt(localPoint);
- TToolsPalette* palette = GetToolsPalette();
- short currentTool = palette->GetCurrTool();
-
- if (currentTool == 0) // Selection
- {
- Boolean cursorSet = fShapeDocument->CursorInShape(qdPoint, cursorRegion);
- if (!cursorSet)
- {
- if (qNeedsColorQD || gConfiguration.hasColorQD)
- SetCCursor(gRainbowArrow); // set cursor to color arrow
- else
- SetCursor(&qd.arrow);
- }
- }
- else
- {
- UseROMMap(true);
- SetCursor(*GetCursor(crossCursor));
- CRect qdExtent;
- GetQDExtent(qdExtent);
- RectRgn(cursorRegion, qdExtent);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // TShapeView::Draw
- //----------------------------------------------------------------------------------------
- #pragma segment ARes
-
- void TShapeView::Draw(const VRect& area) // Override
- {
- CRect qdArea;
- ViewToQDRect(area, qdArea);
- fShapeDocument->DrawShapes(qdArea, fDragging);
-
- Inherited::Draw(area);
- }
-
- //----------------------------------------------------------------------------------------
- // TShapeView::InvalShape
- //----------------------------------------------------------------------------------------
- #pragma segment ShapeRes
-
- void TShapeView::InvalShape(TShape* aShape)
- {
- CRect r;
- aShape->GetFrame(r);
- InsetRect(r, -2, -2);
- InvalidateRect(r);
- }
-
- //----------------------------------------------------------------------------------------
- // TShapeView::RestoreSelection
- //----------------------------------------------------------------------------------------
- #pragma segment ShapeRes
-
- void TShapeView::RestoreSelection()
- {
- this->Focus();
- this->Deselect();
-
- fShapeDocument->RestoreSelection(this);
- }
-
- //----------------------------------------------------------------------------------------
- // TShapeView::SaveSelection
- //----------------------------------------------------------------------------------------
- #pragma segment ShapeRes
-
- void TShapeView::SaveSelection(Boolean andInval)
- {
- this->Focus();
-
- fShapeDocument->SaveSelection(this, andInval);
- }
-
- //----------------------------------------------------------------------------------------
- // TShapeView::WriteToDeskScrap
- //----------------------------------------------------------------------------------------
- #pragma segment AClipboard
-
- void TShapeView::WriteToDeskScrap() // Override
- {
- short count;
- CRect bBox;
- short wantBytes; // long???
- PShapesOnClipboard clipShapes; // pointer to a ShapeClipRecord
-
- // Write the PICT scrap first in case we will be unable to write both
- // the PICT scrap and our own scrap type.
- Inherited::WriteToDeskScrap(); // Generate PICT-type scrap
-
- fShapeDocument->SurveyShapes(false, count, bBox); // count shapes
- wantBytes = sizeof(short) + sizeof(Rect) + (count * sizeof(ShapeData));
- ShapeClipRecord** shapeClipRecHandle = (ShapeClipRecord**)NewPermHandle(wantBytes);
- clipShapes = *shapeClipRecHandle;
- clipShapes->theBoundingBox = bBox;
- clipShapes->theNumberOfShapes = count;
-
- // Copy each shape to the desk scrap
- short i = 0;
- CShapeIterator iter(fShapeDocument->GetShapeList());
- for (TShape* shape = iter.FirstShape(); iter.More(); shape = iter.NextShape())
- {
- ShapeData aShapeDatum;
- aShapeDatum.theId = shape->GetID();
- aShapeDatum.thePattern = shape->GetPattern();
- shape->GetColor(aShapeDatum.theColor);
- CRect extent;
- shape->GetFrame(extent);
- aShapeDatum.theRect = extent;
- clipShapes->theShapes[i] = aShapeDatum;
- i++;
- }
-
- OSErr err = gClipboardMgr->PutDeskScrapData(kShapeClipType, (Handle)shapeClipRecHandle);
- DisposeIfHandle((Handle)shapeClipRecHandle);
- FailOSErr(err);
- }
-
- //----------------------------------------------------------------------------------------
- // TShapeView::ReadFromDeskScrap
- // Launch a view to represent the data found in the Clipboard at application start-up
- // time, or when switching back in, or when returning from a Desk Accessory.
- //----------------------------------------------------------------------------------------
- #pragma segment AClipboard
-
- void TShapeView::ReadFromDeskScrap()
- {
- MAVolatileInit(ShapesOnClipboard, clipShapes, NULL);
-
- FailInfo fi;
- Try(fi)
- {
- clipShapes = (ShapesOnClipboard)NewPermHandle(0);
- FailSpaceIsLow();
-
- Boolean perm = PermAllocation(true);
- long offset;
- long result;
- result = GetScrap((Handle)clipShapes, kShapeClipType, &offset);
- PermAllocation(perm);
-
- // Only a negative result indicates an error,
- // but FailOSErr considers any non-zero result an error.
- if (result < 0) FailOSErr((OSErr)result);
-
- // Read the shapes from the clipboard and add them to the document
- short shapeCount = (*clipShapes)->theNumberOfShapes;
- for (short i=0; i < shapeCount; i++)
- {
- ShapeDataPtr p = (ShapeDataPtr) &(*clipShapes)->theShapes[i];
- TShape* oldShape = GetShapeInArray(p->theId);
- if (oldShape)
- {
- TShape* aNewShape = (TShape*)oldShape->Clone();
- aNewShape->SetFields(p->thePattern, p->theColor, p->theRect);
- fShapeDocument->AddShape(aNewShape);
- }
- }
- fi.Success();
- }
- else // Recover
- {
- DisposeIfHandle((Handle)clipShapes);
- fi.ReSignal();
- }
- DisposeIfHandle((Handle)clipShapes);
- }
-
- //----------------------------------------------------------------------------------------
- // TShapeView::IsMenuColor
- //----------------------------------------------------------------------------------------
- #pragma segment ASelCommand
-
- Boolean TShapeView::IsMenuColor(CommandNumber aCommandNumber)
- {
- short menu;
- short item;
- CommandToMenuItem(aCommandNumber, menu, item);
- if (menu != mColor)
- return false;
-
- MCEntryPtr pMCEntry = GetMCEntry(menu, item);
- CRGBColor theColor = pMCEntry->mctRGB2;
- TRecolorCmd* recolorCmd = new TRecolorCmd;
- recolorCmd->IRecolorCmd(theColor, this);
- this->PostCommand(recolorCmd);
- return true;
- }
-
- //----------------------------------------------------------------------------------------
- // TShapeView::PickColor
- //----------------------------------------------------------------------------------------
- #pragma segment ASelCommand
-
- void TShapeView::PickColor()
- {
- CRGBColor theColor;
-
- // Get the color of the first selected shape
- TShape* shape = fShapeDocument->FirstSelectedShape();
- shape->GetColor(theColor);
- StringHandle pickerPrompt = GetString(kPickerPrompt);
- FailNIL(pickerPrompt);
- if (GetColor(CPoint(-1,-1), *pickerPrompt, theColor, theColor))
- {
- TRecolorCmd* recolorCmd = new TRecolorCmd;
- recolorCmd->IRecolorCmd(theColor, this);
- this->PostCommand(recolorCmd);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // TShapeView::SelectAllShapes
- //----------------------------------------------------------------------------------------
- #pragma segment ASelCommand
-
- void TShapeView::SelectAllShapes()
- {
- fShapeDocument->SelectAllShapes(this);
- }
-
-
-